package Controlador;

import java.text.DateFormat;
import java.text.SimpleDateFormat;
import java.util.Calendar;
import java.util.Date;
import java.util.Vector;

import Modelo.Adicional;
import Modelo.Base;
import Modelo.Cliente;
import Modelo.Consumo;
import Modelo.Dato;
import Modelo.DubCliente;
import Modelo.Factura;
import Modelo.ItemFactura;
import Modelo.Linea;
import Modelo.LineaAdicional;
import Modelo.LineaTitular;
import Modelo.Mail;
import Modelo.PaquetedeServicios;
import Modelo.Plan;
import Modelo.Prepago;
import Modelo.SMS;
import Modelo.Servicio;
import Modelo.Voz;
import Persistencia.AdministradorPersistenciaCliente;

public class Sistema {
 
	private static Sistema instancia;
	private Vector<Cliente> clientes;
	private Vector<Servicio> servicios;
	private Vector<Plan> planes;
	private Vector<Linea> lineas;	
	private Vector<Factura> facturas;
	private Mail m;

	private Sistema() 
	{
		Mail m = new Mail();
		clientes = new Vector<Cliente>();
		servicios = new Vector<Servicio>();
		planes = new Vector<Plan>();
		lineas = new Vector<Linea>();
		facturas = new Vector<Factura>();
		cargaServicio();
		cargaPlanes();
		inicializarSistema();
	}
	
	
	
	public static Sistema getInstancia()
	{
		if (instancia== null)
			instancia = new Sistema();
		return instancia;
	}
	
	
//ADMINISTRACION DE CLIENTES//	
	
	public boolean altaCliente (String doc , String apellido ,String nombre, String domicilio, int telefono, String email, int estado  ) 
	{
		Cliente c = buscarCliente(doc);
		if ( c == null)
			{
			c = new Cliente(doc, apellido,nombre, domicilio, telefono, email, estado);
			clientes.add(c);
			return c.altaCliente(c);
			}		
		return false;				
	}
	
	
	public Cliente buscarCliente(String dni) {
		
		for (int i = 0; i < clientes.size(); i++) 
		{
			Cliente c = clientes.elementAt(i);
			if (c.getDni().equalsIgnoreCase(dni)) 
			{
			 return c;
			}
		}		
		Cliente c1 = new Cliente();
		c1 = c1.buscarCliente(dni);
		if (c1 != null)
		{
		 clientes.add(c1);
		 for (Linea l:c1.getLineas()){
			 lineas.add(l);
		 }
		}		
		return c1;
	}
	
	
	public boolean existeCliente(String dni) {
		boolean existe = false;
		
		for (int i = 0; i < clientes.size(); i++) 
		{
			Cliente c = clientes.elementAt(i);
			if (c.getDni().equalsIgnoreCase(dni)) 
			{
				existe = true;
				return existe;
			}
		}		
		Cliente c1 = new Cliente();
		c1 = c1.buscarCliente(dni);
		if (c1 != null)
		{
			clientes.add(c1);
			existe = true;
			return existe;
		}		
		return existe;
	}
	
	
	
	
	
	public boolean actualizarCliente(String dni, String apellido, String nombre, String domicilio, int telefono, String email, int estado) {
		
	  for (int i = 0; i < clientes.size(); i++) 
		{
			Cliente c = clientes.elementAt(i);
			if (c.getDni().equalsIgnoreCase(dni)) 
			{
				clientes.elementAt(i).setApellido(apellido);
				clientes.elementAt(i).setNombre(nombre);
				clientes.elementAt(i).setDomicilio(domicilio);
				clientes.elementAt(i).setTelefono(telefono);
				clientes.elementAt(i).setEmail(email);
			}
		}
		
		Cliente c1 = new Cliente(dni, apellido, nombre, domicilio, telefono, email, estado);
		return AdministradorPersistenciaCliente.getInstancia().update(c1);
	}
	
	

	
	public DubCliente buscarClienteMostrar (String dni) {
			Cliente c = buscarCliente(dni);			
			if (c != null) 
			{	
			DubCliente a = new DubCliente(c.getDni(),  c.getApellido() ,c.getNombre(), c.getDomicilio(), c.getTelefono(), c.getEmail(), c.getEstado() );
			return a;
			}		
		return null;
	}

	public void switchCliente(String dni, int valor) {
		
		for (int i = 0; i < clientes.size(); i++) 
		{ 
			Cliente c = clientes.elementAt(i);
			if (c.getDni().equalsIgnoreCase(dni)) 
			{
				clientes.elementAt(i).setEstado(valor);
				AdministradorPersistenciaCliente.getInstancia().update(c);
			}
		}
	}	

	
	
	
	//MANEJO DE SERVICIOS//
	
	public boolean altaServicioSms (String nombre , String tipo, String unidad ,float valorSms, int cantSmsLibre, float costo) 
	{
			int cantSrv = servicios.size();
			
			SMS s = new SMS(cantSrv + 1, unidad, nombre, tipo , valorSms, cantSmsLibre, costo);
			servicios.add(s);
			SMS.altaServicioSms(s);
		return true;				
	}
	
	
	public boolean altaServicioDatos (String nombre , String tipo,String unidad ,float valorKb, int cantKbLibre, float costo) 
	{
		int cantSrv = servicios.size();	 
		Dato d = new Dato(cantSrv + 1, unidad, nombre, tipo , valorKb, cantKbLibre, costo);
			servicios.add(d);
			Dato.altaServicioDato(d);
		return true;				
	}
	
	public boolean altaServicioVoz (String nombre , String tipo,String unidad ,float valorMin, int cantMinLibre, float costo) 
	{
		int cantSrv = servicios.size();	 
		Voz v = new Voz(cantSrv + 1, unidad, nombre, tipo , valorMin, cantMinLibre, costo);
			servicios.add(v);
			Voz.altaServicioVoz(v);
		return true;				
	}

	public boolean altaPaquete (String nombre , String tipo,String unidad ,float descuento,  Vector<String> servicioPaq ) 
	{
		int cantSrv = servicios.size();	 
		PaquetedeServicios nvoPaq = new PaquetedeServicios(cantSrv + 1, unidad, nombre, tipo , descuento);
		
		for (int i = 0; i < servicioPaq.size(); i++) 
		{ 
		 nvoPaq.addServicios(getServicioPorNombre(servicioPaq.elementAt(i)));
		} 
		  servicios.add(nvoPaq);
		  PaquetedeServicios.altaServicioPaquete(nvoPaq);
		return true;				
	}


	//MANEJO DE PLANES//
	
	public Plan getPlanId(int id)
	{
		return this.buscarPlanId(id);
	}
	
	
	public boolean altaPlan (String nombre, float costoExd, String tipoPlan ,Vector<String> servicioPlan )
	{			
		int cantPlan;
		if(planes.isEmpty()){
			cantPlan = 0;
		}else
		{	cantPlan = planes.size();
			
		};
			
		if (tipoPlan =="ADICIONAL"){
			Adicional
			nvoPlan = new Adicional(nombre, cantPlan + 1,tipoPlan,  costoExd);
			for (int i = 0; i < servicioPlan.size(); i++) 
			{ 
			 nvoPlan.addServicios(getServicioPorNombre(servicioPlan.elementAt(i)));			 			 
			}
			planes.add(nvoPlan);
			Adicional.altaPlanAdicional(nvoPlan);
			
		};
		if (tipoPlan =="PREPAGO"){
			Prepago nvoPlan = new Prepago (nombre, cantPlan + 1,tipoPlan);
			for (int i = 0; i < servicioPlan.size(); i++) 
			{ 
			 nvoPlan.addServicios(getServicioPorNombre(servicioPlan.elementAt(i)));			 
			}
			planes.add(nvoPlan);
			Prepago.altaPlanPrepago(nvoPlan);
		};
		if (tipoPlan =="BASE"){
			Base nvoPlan = new Base(nombre, cantPlan + 1,  tipoPlan);
			for (int i = 0; i < servicioPlan.size(); i++) 
			{ 
			 nvoPlan.addServicios(getServicioPorNombre(servicioPlan.elementAt(i)));			 
			}
			planes.add(nvoPlan);
			Base.altaPlanBase(nvoPlan);
		};
		
		return true;
	}
	

	public Plan buscarPlanId(int idPlan) {
		
		for (int i = 0; i < planes.size(); i++) 
		{
			Plan p = planes.elementAt(i);
			if (p.getNroPlan() == idPlan) 
			{
			 return p;
			}
		}		
		return null;
	}
	
	//MANEJO DE LINEA//
	
	public void AltaLineaAdicional (int numero, String tipoLinea, String unDni, String unPlan , String nombreAdicional )
	{
		Cliente c = buscarCliente(unDni);
		LineaAdicional nvaLinea = new LineaAdicional(numero, tipoLinea, getPlanPorNombre(unPlan), nombreAdicional );
		lineas.add(nvaLinea);
		c.addLinea(nvaLinea);
		LineaAdicional.altaLineaAdicional(nvaLinea, unDni);
	}
	
	public void AltaLineaTitular (int numero, String tipoLinea, String unDni, String unPlan )
	{
		Cliente c = buscarCliente(unDni);
		LineaTitular nvaLinea = new LineaTitular(numero, tipoLinea , getPlanPorNombre(unPlan) );
		lineas.add(nvaLinea);
		c.addLinea(nvaLinea);
		LineaTitular.altaLineaTitular(nvaLinea, unDni);
	}
	
	
	
	//MANEJO DE CONSUMOS//
	
	public void altaConsumo (int cantidadUnidadesConsumidas, int servicioId, String destinatario, String dni, int unaLinea)
	{
		Cliente c = buscarCliente(dni);
		Linea laLinea = c.getLineaPorNumero(unaLinea);
		Consumo nvoConsumo = new Consumo(cantidadUnidadesConsumidas, getServicioPorId(servicioId), destinatario);
		laLinea.addConsumo(nvoConsumo);		
	}
	
	public void insertConsumo (String dni, int unaLinea)
	{
		Cliente c = buscarCliente(dni);
		Linea laLinea = c.getLineaPorNumero(unaLinea);
		laLinea.insertConsumoALinea(laLinea);
	}
	

private void inicializarSistema(){
		
		
		//Alta de Servicios SMS
		/*this.altaServicioSms("SMS1","SMS", "MENSAJES", Float.valueOf("0.25"),   Integer.valueOf("50"), Float.valueOf("10"));
		this.altaServicioSms("SMS2","SMS", "MENSAJES", Float.valueOf("0.20"),  Integer.valueOf("100"), Float.valueOf("30"));
		this.altaServicioSms("SMS3","SMS", "MENSAJES", Float.valueOf("0.15"),  Integer.valueOf("500"), Float.valueOf("50"));
		this.altaServicioSms("SMS4","SMS", "MENSAJES", Float.valueOf("0.10"),  Integer.valueOf("1000"), Float.valueOf("70"));
		
		this.altaServicioVoz("VOZ1","VOZ", "MINUTOS", Float.valueOf("0.45"),   Integer.valueOf("50"), Float.valueOf("30"));
		this.altaServicioVoz("VOZ2","VOZ", "MINUTOS", Float.valueOf("0.30"),  Integer.valueOf("100"), Float.valueOf("50"));
		this.altaServicioVoz("VOZ3","VOZ", "MINUTOS", Float.valueOf("0.25"),  Integer.valueOf("300"), Float.valueOf("80"));
		this.altaServicioVoz("VOZ4","VOZ", "MINUTOS", Float.valueOf("0.20"),  Integer.valueOf("1000"), Float.valueOf("120"));
		
		this.altaServicioDatos("DATOS1","DATOS", "KB", Float.valueOf("0.45"),   Integer.valueOf("50"), Float.valueOf("30"));
		this.altaServicioDatos("DATOS2","DATOS", "KB", Float.valueOf("0.30"),  Integer.valueOf("100"), Float.valueOf("50"));
		this.altaServicioDatos("DATOS3","DATOS", "KB", Float.valueOf("0.25"),  Integer.valueOf("300"), Float.valueOf("80"));
		this.altaServicioDatos("DATOS4","DATOS", "KB", Float.valueOf("0.20"),  Integer.valueOf("1000"), Float.valueOf("120"));*/
				
		/*this.altaCliente("31303153", "LOPEZ", "EMILIANO", "SAN CARLOS 1345", Integer.valueOf("47572515"), "elopezIturriche@gmail.com");
		this.altaCliente("33104426", "Lucero", "German", "Una Calle 1234", Integer.valueOf("1111111"), "glucero@gmail.com");
		this.altaCliente("23", "LOPEZ", "EMILIANO", "Una Calle 1", Integer.valueOf("2222222"), "xxxx@gmail.com");
		this.altaCliente("12", "LOPEZ", "EMILIANO", "Una Calle 2", Integer.valueOf("3333333"), "xxxx@gmail.com");*/
		
		
		//ALTA DE PLANES//
	    /*Vector<String> servicioPlan = new Vector<String>();
		servicioPlan.add("VOZ1");
		servicioPlan.add("DATOS1");
		this.altaPlan("ANIVERSARIO", Float.valueOf("0.45"), "BASE", servicioPlan);
		
		Vector<String> servicioPlan1 = new Vector<String>();
		servicioPlan.add("VOZ2");
		servicioPlan.add("DATOS3");
		servicioPlan.add("SMS1");
		this.altaPlan("PRIMAVERA", Float.valueOf("0.45"), "BASE", servicioPlan1);*/
		
		
		//ALTA DE LINEA//
		/*this.AltaLineaTitular(Integer.valueOf("1"), "TITULAR", "31303153", "ANIVERSARIO");
		this.AltaLineaAdicional(Integer.valueOf("2"), "ADICINAL", "31303153", "PRIMAVERA","GISELA");*/
		
		
 	    this.altaConsumo(Integer.parseInt("1"), 1, "1234", "31303153", Integer.parseInt("43402573"));
	    this.altaConsumo(Integer.parseInt("2"), 2, "1234", "31303153", Integer.parseInt("43402573"));
	    this.altaConsumo(Integer.parseInt("3"), 1, "1234", "31303153", Integer.parseInt("43402573"));
	    this.altaConsumo(Integer.parseInt("4"), 2, "1234", "31303153", Integer.parseInt("43402573"));
	    
	    this.altaConsumo(Integer.parseInt("1"), 1, "1234", "33104426", Integer.parseInt("43402548"));
	    this.altaConsumo(Integer.parseInt("2"), 2, "1234", "33104426", Integer.parseInt("43402548"));
	    this.altaConsumo(Integer.parseInt("3"), 1, "1234", "33104426", Integer.parseInt("43402548"));
	    this.altaConsumo(Integer.parseInt("4"), 2, "1234", "33104426", Integer.parseInt("43402548"));
	    this.insertConsumo("31303153", Integer.parseInt("43402573"));
	    this.insertConsumo("33104426", Integer.parseInt("43402548"));	
		}
		



public void cargaPlanes() 
{
	planes = Plan.planesCarga();
}

public void cargaServicio() 
{
	servicios = Servicio.servicioCarga();
}

public Vector<String> cargaComboSms(String smsSrv)
{
 Vector<String> vSmsSrv = new Vector<String>();
 
 for (int i = 0; i < servicios.size(); i++) 
	{
	 Servicio auxSrv = servicios.elementAt(i);
	 if (auxSrv.getTipo().equalsIgnoreCase(smsSrv)) 
	 {	 
	 SMS s = (SMS) servicios.elementAt(i);
		if (s.getTipo().equalsIgnoreCase(smsSrv)) 
		{
			String aux = s.getNombre();
			vSmsSrv.add(aux);
		}
	 }
	}		
 
 return vSmsSrv;
}

public Vector<String> cargaComboDatos(String datoSrv)
{
 Vector<String> vDatoSrv = new Vector<String>();
 
 for (int i = 0; i < servicios.size(); i++) 
	{
	 Servicio auxSrv = servicios.elementAt(i);
	 if (auxSrv.getTipo().equalsIgnoreCase(datoSrv)) 
	 {	 
	 Dato d = (Dato) servicios.elementAt(i);
		if (d.getTipo().equalsIgnoreCase(datoSrv)) 
		{
			String aux = d.getNombre();
			vDatoSrv.add(aux);
		}
	 }
	}		
 
 return vDatoSrv;
}

public Vector<String> cargaComboVoz(String smsSrv)
{
 Vector<String> vSmsSrv = new Vector<String>();
 
 for (int i = 0; i < servicios.size(); i++) 
	{
	 Servicio auxSrv = servicios.elementAt(i);
	 if (auxSrv.getTipo().equalsIgnoreCase(smsSrv)) 
	 {	 
	 Voz s = (Voz) servicios.elementAt(i);
		if (s.getTipo().equalsIgnoreCase(smsSrv)) 
		{
			String aux = s.getNombre();
			vSmsSrv.add(aux);
		}
	 }
	}		
 
 return vSmsSrv;
}

public Vector<String> cargaComboPaquete(String paqSrv)


{
 Vector<String> vPaqSrv = new Vector<String>();
 
 for (int i = 0; i < servicios.size(); i++) 
	{
	 Servicio auxSrv = servicios.elementAt(i);
	 if (auxSrv.getTipo().equalsIgnoreCase(paqSrv)) 
	 {	 
		 PaquetedeServicios s = (PaquetedeServicios) servicios.elementAt(i);
		if (s.getTipo().equalsIgnoreCase(paqSrv)) 
		{
			String aux = s.getNombre();
			vPaqSrv.add(aux);
		}
	 }
	}		
 
 return vPaqSrv;
}

public Vector<String> cargaComboPlan()
{
	
	Vector<String> vPlan = new Vector<String>();
	 
	 for (int i = 0; i < planes.size(); i++) 
		{
		 Plan auxPlan = planes.elementAt(i);
		 String aux = auxPlan.getNombre();
		 vPlan.add(aux);
		}
	 return vPlan;
   }


public Servicio getServicioPorNombre(String nombre)
{	
	for (int i = 0; i < servicios.size(); i++) 
	{
	 Servicio auxSrv = servicios.elementAt(i);
	 if (auxSrv.getNombre().equalsIgnoreCase(nombre)) 
	 {	 
		 return  servicios.elementAt(i);		
	 }
	}
	
	return null;	
}

public Servicio getServicioPorId(int servicioId)
{	
	for (int i = 0; i < servicios.size(); i++) 
	{
	 Servicio auxSrv = servicios.elementAt(i);
	 if (auxSrv.getId() == servicioId) 
	 {	 
		 return  servicios.elementAt(i);		
	 }
	}
	
	return null;	
}

public Plan getPlanPorNombre(String nombre)
{	
	for (int i = 0; i < planes.size(); i++) 
	{
	 Plan auxPlan = planes.elementAt(i);
	 if (auxPlan.getNombre().equalsIgnoreCase(nombre)) 
	 {	 
		 return  planes.elementAt(i);		
	 }
	}
	
	return null;	
}

	
public int getCantLineaPorCliente (String dni)
   {
	Cliente c = buscarCliente(dni);
	return c.lineasPorCliente();
   }



public void FacturarMes(Date mes){
	//PARA CADA CLIENTE
		for (Cliente c : this.clientes) {
			Factura f = new Factura();
			 f = f.facturarCliente(facturas.size()+1, c, mes);
			 if (f != null){
				 facturas.add(f);
				 f.altaFactura(f);
				 if (c.getEmail() != null){
					 
					 Calendar cal =Calendar.getInstance();
					 cal.setTime(f.getPeriodo());
					 cal.add(Calendar.MONTH, 1);

					 EnviarEmail(c.getEmail(), f.getTotal(),  cal.getTime());
				 }
			 }					
		}
}


public void EnviarEmail(String email, float total, Date vencimiento){
	DateFormat df = new SimpleDateFormat("dd/MM/yyyy");		
	Mail.enviarMail(email,"Facturacion Mensual Telefonico","Usted tiene una factura pendiente. Monto: $" + String.valueOf(total) +". Con fecha de vencimiento: " + df.format(vencimiento));
}
	
	


}
	
